package com.nnnu.wsnackshop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.nnnu.wsnackshop.exception.ObjectException;
import com.nnnu.wsnackshop.mapper.CartItemsMapper;
import com.nnnu.wsnackshop.mapper.ProductSkuMapper;
import com.nnnu.wsnackshop.mapper.ProductsMapper;
import com.nnnu.wsnackshop.pojo.dto.CartItemAddDTO;
import com.nnnu.wsnackshop.pojo.dto.CartItemUpdateDTO;
import com.nnnu.wsnackshop.pojo.entity.CartItems;
import com.nnnu.wsnackshop.pojo.entity.Carts;
import com.nnnu.wsnackshop.mapper.CartsMapper;
import com.nnnu.wsnackshop.pojo.entity.ProductSku;
import com.nnnu.wsnackshop.pojo.entity.Products;
import com.nnnu.wsnackshop.pojo.vo.CartItemVO;
import com.nnnu.wsnackshop.pojo.vo.CartVO;
import com.nnnu.wsnackshop.pojo.vo.ProductSimpleVO;
import com.nnnu.wsnackshop.pojo.vo.ProductSkuVO;
import com.nnnu.wsnackshop.service.ICartsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 购物车 服务实现类
 * </p>
 *
 * @author zk
 * @since 2025-05-14
 */
@Service
@RequiredArgsConstructor
public class CartsServiceImpl extends ServiceImpl<CartsMapper, Carts> implements ICartsService {

    private final CartItemsMapper cartItemsMapper;

    private final ProductsMapper productsMapper;

    private final ProductSkuMapper productSkuMapper;

    private Carts getOrCreateCart(Integer userId) {
        LambdaQueryWrapper<Carts> cartQueryWrapper = new LambdaQueryWrapper<>();
        cartQueryWrapper.eq(Carts::getUserId, userId);
        Carts cart = baseMapper.selectOne(cartQueryWrapper);

        if (cart == null) {
            cart = new Carts();
            cart.setUserId(userId);
            cart.setUpdatedAt(LocalDateTime.now());
            baseMapper.insert(cart);
        }
        return cart;
    }

    @Override
    public CartVO getCartByUserId(Integer userId) {
        // 获取或创建购物车
        Carts cart = getOrCreateCart(userId);

        // 查询用户购物车商品
        LambdaQueryWrapper<CartItems> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CartItems::getCartId, cart.getId())
                .eq(CartItems::getUserId, userId);
        List<CartItems> cartItemsList = cartItemsMapper.selectList(queryWrapper);

        // 构建购物车VO
        CartVO cartVO = new CartVO();
        cartVO.setUserId(userId);

        // 如果购物车为空，返回空购物车
        if (cartItemsList.isEmpty()) {
            cartVO.setTotalQuantity(0);
            cartVO.setTotalAmount(BigDecimal.ZERO);
            cartVO.setItems(new ArrayList<>());
            return cartVO;
        }

        // 获取所有商品ID和规格ID
        List<Integer> productIds = cartItemsList.stream()
                .map(CartItems::getProductId)
                .distinct()
                .collect(Collectors.toList());

        List<Integer> skuIds = cartItemsList.stream()
                .map(CartItems::getSkuId)
                .distinct()
                .collect(Collectors.toList());

        // 查询商品信息
        LambdaQueryWrapper<Products> productQueryWrapper = new LambdaQueryWrapper<>();
        productQueryWrapper.in(Products::getId, productIds);
        List<Products> productsList = productsMapper.selectList(productQueryWrapper);
        Map<Integer, Products> productsMap = productsList.stream()
                .collect(Collectors.toMap(Products::getId, Function.identity()));

        // 查询规格信息
        LambdaQueryWrapper<ProductSku> skuQueryWrapper = new LambdaQueryWrapper<>();
        skuQueryWrapper.in(ProductSku::getId, skuIds);
        List<ProductSku> skuList = productSkuMapper.selectList(skuQueryWrapper);
        Map<Integer, ProductSku> skuMap = skuList.stream()
                .collect(Collectors.toMap(ProductSku::getId, Function.identity()));

        // 构建购物车商品列表
        List<CartItemVO> cartItemVOList = cartItemsList.stream().map(cartItem -> {
            CartItemVO cartItemVO = new CartItemVO();
            cartItemVO.setId(cartItem.getId());
            cartItemVO.setQuantity(cartItem.getQuantity());
            cartItemVO.setSelected(cartItem.getSelected() != null && cartItem.getSelected() == 1);

            // 商品信息
            Products product = productsMap.get(cartItem.getProductId());
            if (product != null) {
                ProductSimpleVO productSimpleVO = new ProductSimpleVO();
                productSimpleVO.setId(product.getId());
                productSimpleVO.setName(product.getName());
                productSimpleVO.setImage(product.getMainImage());
                productSimpleVO.setCategoryId(product.getCategoryId());
                // 可以继续设置其他商品属性
                cartItemVO.setProduct(productSimpleVO);
            }

            // 规格信息
            ProductSku sku = skuMap.get(cartItem.getSkuId());
            if (sku != null) {
                ProductSkuVO skuVO = new ProductSkuVO();
                skuVO.setId(sku.getId());
                skuVO.setProductId(sku.getProductId());
                skuVO.setSkuCode(sku.getSkuCode());
                skuVO.setSkuName(sku.getTitle());
                skuVO.setSpecs(sku.getSpecSnCombination());
                skuVO.setPrice(sku.getPrice());
                skuVO.setOriginalPrice(sku.getPrice());
                skuVO.setStock(sku.getStock());
                // 可以继续设置其他规格属性
                cartItemVO.setSku(skuVO);
            }

            return cartItemVO;
        }).collect(Collectors.toList());

        // 计算总数量和总金额
        int totalQuantity = cartItemsList.stream()
                .mapToInt(CartItems::getQuantity)
                .sum();

        BigDecimal totalAmount = cartItemVOList.stream()
                .filter(item -> item.getSku() != null && item.getSelected())
                .map(item -> item.getSku().getPrice().multiply(new BigDecimal(item.getQuantity())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        cartVO.setItems(cartItemVOList);
        cartVO.setTotalQuantity(totalQuantity);
        cartVO.setTotalAmount(totalAmount);

        return cartVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addCartItem(Integer userId, CartItemAddDTO cartItemAddDTO) {
        // 验证商品和规格是否存在
        Products product = productsMapper.selectById(cartItemAddDTO.getProductId());
        if (product == null) {
            throw new ObjectException("商品不存在");
        }

        ProductSku sku = productSkuMapper.selectById(cartItemAddDTO.getSkuId());
        if (sku == null) {
            throw new ObjectException("商品规格不存在");
        }

        // 验证库存
        if (sku.getStock() < cartItemAddDTO.getQuantity()) {
            throw new ObjectException("商品库存不足");
        }

        Carts cart = getOrCreateCart(userId);

        // 检查该商品规格是否已在购物车中
        LambdaQueryWrapper<CartItems> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CartItems::getCartId, cart.getId())
                .eq(CartItems::getProductId, cartItemAddDTO.getProductId())
                .eq(CartItems::getSkuId, cartItemAddDTO.getSkuId());
        CartItems existingCartItem = cartItemsMapper.selectOne(queryWrapper);

        if (existingCartItem != null) {
            // 已存在，更新数量
            int newQuantity = existingCartItem.getQuantity() + cartItemAddDTO.getQuantity();
            if (newQuantity > sku.getStock()) {
                throw new ObjectException("商品库存不足");
            }

            existingCartItem.setQuantity(newQuantity);
            existingCartItem.setUpdatedAt(LocalDateTime.now());
            return cartItemsMapper.updateById(existingCartItem) > 0;
        } else {
            // 不存在，新增
            CartItems cartItem = new CartItems();
            cartItem.setCartId(cart.getId());
            cartItem.setUserId(userId);
            cartItem.setProductId(cartItemAddDTO.getProductId());
            cartItem.setSkuId(cartItemAddDTO.getSkuId());
            cartItem.setQuantity(cartItemAddDTO.getQuantity());
            cartItem.setSelected(1); // 默认选中
            cartItem.setCreatedAt(LocalDateTime.now());
            cartItem.setUpdatedAt(LocalDateTime.now());
            return cartItemsMapper.insert(cartItem) > 0;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCartItem(Integer userId, Integer cartItemId, CartItemUpdateDTO cartItemUpdateDTO) {
        // 查询购物车商品
        LambdaQueryWrapper<CartItems> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CartItems::getId, cartItemId)
                .eq(CartItems::getUserId, userId);
        CartItems cartItem = cartItemsMapper.selectOne(queryWrapper);

        if (cartItem == null) {
            throw new ObjectException("购物车商品不存在");
        }

        // 验证库存
        ProductSku sku = productSkuMapper.selectById(cartItem.getSkuId());
        if (sku == null) {
            throw new ObjectException("商品规格不存在");
        }

        if (sku.getStock() < cartItemUpdateDTO.getQuantity()) {
            throw new ObjectException("商品库存不足");
        }

        // 更新数量
        cartItem.setQuantity(cartItemUpdateDTO.getQuantity());
        cartItem.setUpdatedAt(LocalDateTime.now());
        return cartItemsMapper.updateById(cartItem) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteCartItem(Integer userId, Integer cartItemId) {
        // 验证购物车项是否存在并属于该用户
        CartItems cartItem = cartItemsMapper.selectById(cartItemId);
        if (cartItem == null || !cartItem.getUserId().equals(userId)) {
            throw new ObjectException("购物车商品不存在");
        }
        return cartItemsMapper.deleteById(cartItemId) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean clearCart(Integer userId) {
        Carts cart = baseMapper.selectOne(new LambdaQueryWrapper<Carts>().eq(Carts::getUserId, userId));
        if (cart == null) {
            return true;
        }
        LambdaQueryWrapper<CartItems> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CartItems::getCartId, cart.getId());
        cartItemsMapper.delete(queryWrapper);
        return true;
    }

    @Override
    public Integer getCartCount(Integer userId) {
        Carts cart = baseMapper.selectOne(new LambdaQueryWrapper<Carts>().eq(Carts::getUserId, userId));
        if (cart == null) {
            return 0;
        }
        return cartItemsMapper.sumCartQuantityByCartId(cart.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean toggleCartItemSelection(Integer userId, Integer cartItemId, Boolean selected) {
        LambdaUpdateWrapper<CartItems> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(CartItems::getId, cartItemId)
                .eq(CartItems::getUserId, userId)
                .set(CartItems::getSelected, selected ? 1 : 0)
                .set(CartItems::getUpdatedAt, LocalDateTime.now());
        return cartItemsMapper.update(null, updateWrapper) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean toggleAllCartItemsSelection(Integer userId, Boolean selected) {
        LambdaUpdateWrapper<CartItems> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(CartItems::getUserId, userId)
                .set(CartItems::getSelected, selected ? 1 : 0)
                .set(CartItems::getUpdatedAt, LocalDateTime.now());
        return cartItemsMapper.update(null, updateWrapper) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchDeleteCartItems(Integer userId, List<Integer> ids) {
        if (ids == null || ids.isEmpty()) {
            return true;
        }
        LambdaQueryWrapper<CartItems> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(CartItems::getId, ids).eq(CartItems::getUserId, userId);
        cartItemsMapper.delete(queryWrapper);
        return true;
    }
}
